package com.friend.chat.media.video

import android.Manifest
import android.app.Activity
import android.content.Intent
import android.media.MediaPlayer
import android.util.Log
import android.view.View
import com.friend.chat.R
import com.friend.chat.base.BaseActivity
import com.friend.chat.base.BasicViewModel
import com.friend.chat.chat.*
import com.friend.chat.databinding.ActivitySingleCallBinding
import com.friend.chat.media.audio.AudioDecoder
import com.friend.chat.media.audio.AudioRecorder
import com.friend.chat.page.bean.UserBean
import com.friend.chat.utils.SPUtils
import com.friend.chat.webrtc.IWebRtcCallback
import com.friend.chat.webrtc.WebRtcEngine
import com.friend.chat.webrtc.renderer.ProxyVideoSink
import com.friend.chat.websocket.ChatMessageBean
import com.friend.chat.websocket.WebSocketManager
import com.google.gson.Gson
import com.permissionx.guolindev.PermissionX
import com.zackratos.ultimatebarx.ultimatebarx.navigationBar
import com.zackratos.ultimatebarx.ultimatebarx.statusBar
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.jetbrains.anko.toast
import org.webrtc.MediaStream
import org.webrtc.RendererCommon
import org.webrtc.SessionDescription
import org.webrtc.SurfaceViewRenderer
import java.util.*
import kotlin.concurrent.schedule


class SingleVideoActivity : BaseActivity<ActivitySingleCallBinding, BasicViewModel>() {
    private var isCall: Boolean = true
    private var mToUid: String = ""
    private lateinit var userBean: UserBean
    private var mWebRtcEngine: WebRtcEngine? = null
    private val TAG = "SingleVideoActivity"

    //接听的时候响铃
    private var mMediaPlayerRingPickup: MediaPlayer? = null

    //拨打的时候响铃
    private var mMediaPlayerRingCall: MediaPlayer? = null

    private var mMediaPlayerHangup: MediaPlayer? = null


    companion object {
        fun open(activity: Activity, toUid: String, isCall: Boolean) {
            val intent = Intent(activity, SingleVideoActivity::class.java)
            intent.putExtra("toUid", toUid)
            //接电话或者是打电话
            intent.putExtra("isCall", isCall)
            activity.startActivity(intent)
        }
    }

    override fun yourViewModel(): BasicViewModel {
        return BasicViewModel()
    }


    override fun yourViewBing(): ActivitySingleCallBinding {
        return ActivitySingleCallBinding.inflate(layoutInflater)
    }

    override fun init() {
        statusBar { transparent() }
        navigationBar { transparent() }

        userBean = SPUtils.getInstance().getObject("user") as UserBean
        isCall = intent.getBooleanExtra("isCall", true)
        mToUid = intent.getStringExtra("toUid") ?: ""

        if (!isCall) {
            findViewById<View>(R.id.outgoingActionContainer).visibility = View.GONE
            findViewById<View>(R.id.incomingActionContainer).visibility = View.VISIBLE
        }

        initRing()

        initClick()

        PermissionX.init(this).permissions(
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.CAMERA
        )
            .request { allGranted, grantedList, deniedList ->
                if (allGranted) {
                    initWebrtc()
                    if (isCall) {
                        WebSocketManager.instance.sendMessage(
                            Gson().toJson(
                                ChatMessageBean(
                                    userBean.uid,
                                    mToUid,
                                    type = CHAT_SYSTEM,
                                    roomType = -1,
                                    RING_VIDEO_ACK
                                )
                            )
                        )
                        mMediaPlayerRingCall?.start()

                    } else {
                        //有电话进来
                        mMediaPlayerRingPickup?.start()
                    }
                }
            }

        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }
    }

    private fun initClick() {
        //接听
        mViewBinding.incomingActionContainer.acceptLinearLayout.setOnClickListener {
            WebSocketManager.instance.sendMessage(
                Gson().toJson(
                    ChatMessageBean(
                        userBean.uid,
                        toUid = mToUid,
                        type = CHAT_SYSTEM,
                        roomType = -1,
                        PICKUP_VIDEO_ACK
                    )
                )
            )
            mViewBinding.incomingActionContainer.hangupLinearLayout.visibility = View.VISIBLE
            mViewBinding.incomingActionContainer.acceptLinearLayout.visibility = View.GONE
            mMediaPlayerRingPickup?.stop()
            val view: View? = mWebRtcEngine?.setupLocalPreview(false)
            view?.apply {
                val localSurfaceView = view as SurfaceViewRenderer
                mViewBinding.fullscreenVideoView.addView(localSurfaceView)
            }

        }

        //挂断
        mViewBinding.incomingActionContainer.hangupLinearLayout.setOnClickListener {
            AudioRecorder.getInstance()?.stopRecording()
            AudioDecoder.getInstance().stopDecoding()
            WebSocketManager.instance.sendMessage(
                Gson().toJson(
                    ChatMessageBean(
                        userBean.uid,
                        mToUid, type = CHAT_SYSTEM,
                        roomType = -1,
                        HANGUP_VIDEO_ACK
                    )
                )
            )
            mMediaPlayerRingCall?.stop()
            mMediaPlayerHangup?.start()
            mMediaPlayerHangup?.setOnCompletionListener {
                finish()
            }
        }
    }

    private fun initRing() {
        mMediaPlayerHangup = MediaPlayer.create(this, R.raw.hangup)
        mMediaPlayerRingPickup = MediaPlayer.create(this, R.raw.phone_ring_pickup)
        mMediaPlayerRingPickup?.isLooping = true
        mMediaPlayerRingCall = MediaPlayer.create(this, R.raw.phone_ring_call)
        mMediaPlayerRingCall?.setOnCompletionListener {
            Timer().schedule(800) {
                mMediaPlayerRingCall?.start()
            }
        }
        mMediaPlayerRingCall?.isLooping = false
    }


    private fun initWebrtc() {
        val uuid = UUID.randomUUID().toString()
        mWebRtcEngine = WebRtcEngine(this, false, object : IWebRtcCallback {
            override fun sendOffer(sdp: SessionDescription?) {
                Log.d(TAG, "sendOffer: sendOffer")
                sdp?.apply {
                    val map = HashMap<String, String>()
                    map["type"] = SIGNAL_OFFER
                    map["sdp"] = sdp.description
                    WebSocketManager.instance.sendMessage(
                        Gson().toJson(
                            ChatMessageBean(
                                userId = userBean.uid,
                                toUid = mToUid,
                                type = CHAT_VIDEO,
                                roomType = CHAT_ROOM_SINGLE,
                                roomId = uuid,
                                message = map
                            )
                        )
                    )
                }

            }

            override fun sendAnswer(sdp: SessionDescription?) {
                Log.d(TAG, "sendAnswer: sendAnswer")
                sdp?.apply {
                    val map = HashMap<String, String>()
                    map["type"] = SIGNAL_ANSWER
                    map["sdp"] = sdp.description
                    WebSocketManager.instance.sendMessage(
                        Gson().toJson(
                            ChatMessageBean(
                                userId = userBean.uid,
                                toUid = mToUid,
                                type = CHAT_VIDEO,
                                roomType = CHAT_ROOM_SINGLE,
                                roomId = uuid,
                                message = map
                            )
                        )
                    )
                }
            }

            override fun sendIceCandidate(sdpMid: String?, sdpMLineIndex: Int, sdp: String?) {
                Log.d(TAG, "sendIceCandidate: sendIceCandidate")
                val map = HashMap<String, Any>()
                map["type"] = SIGNAL_CANDIDATE
                map["sdpMid"] = sdpMid ?: ""
                map["sdpMLineIndex"] = sdpMLineIndex
                map["sdp"] = sdp ?: ""
                WebSocketManager.instance.sendMessage(
                    Gson().toJson(
                        ChatMessageBean(
                            userId = userBean.uid,
                            toUid = mToUid,
                            type = CHAT_VIDEO,
                            roomType = CHAT_ROOM_SINGLE,
                            roomId = uuid,
                            message = map
                        )
                    )
                )
            }

            override fun onRemoteStream(stream: MediaStream?) {
                runOnUiThread {
                    stream?.apply {
                        Log.e(TAG, "onRemoteStream: onRemoteStream${stream.toString()}")
                        val renderer = SurfaceViewRenderer(this@SingleVideoActivity)
                        renderer.init(mWebRtcEngine!!.eglContext, null)
                        renderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL)
                        renderer.setMirror(true)
                        renderer.setZOrderMediaOverlay(true)
                        val sink = ProxyVideoSink()
                        sink.setTarget(renderer)
                        if (stream.videoTracks.size > 0) {
                            stream.videoTracks[0].addSink(sink)
                        }
                        mViewBinding.pipVideoView.addView(renderer)
                    }
                }
            }
        })
        mWebRtcEngine?.personIn(userBean.uid, mToUid)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(event: ChatMessageBean?) {
        event?.apply {
            if (event.type == CHAT_SYSTEM && PICKUP_VIDEO_ACK == event.message) {
                //对方已接听，开始初始化
                mMediaPlayerRingCall?.stop()
                mMediaPlayerRingCall = null
                Log.d("--->", "对方已接听，开始录制")
                mWebRtcEngine?.createOffer(userBean.uid)
                val view: View? = mWebRtcEngine?.setupLocalPreview(false)
                view?.apply {
                    val localSurfaceView = view as SurfaceViewRenderer
                    mViewBinding.fullscreenVideoView.addView(localSurfaceView)
                }
            } else if (event.type == CHAT_SYSTEM && HANGUP_VIDEO_ACK == event.message) {
                toast("对方已挂断电话")
                mMediaPlayerHangup?.start()

                Timer().schedule(1000) {
                    finish()
                }
            }


            if (event.type == CHAT_VIDEO && event.roomType == CHAT_ROOM_SINGLE) {
                Log.d(TAG, "onMessageEvent: 记录回调${event.message}")
                val map = message as Map<String, String>
                val type = map["type"]
                //接收者：接收到offer
                if (SIGNAL_OFFER == type) {
                    Log.d(TAG, "onMessageEvent: receiveOffer")
                    mWebRtcEngine?.receiveOffer(userBean.uid, map["sdp"].toString())
                }
                //发送者：接收到answer
                else if (SIGNAL_ANSWER == type) {
                    Log.d(TAG, "onMessageEvent: receiveAnswer")
                    mWebRtcEngine?.receiveAnswer(userBean.uid, map["sdp"].toString())
                }
                //所有参与的
                else if (SIGNAL_CANDIDATE == type) {
                    Log.d(TAG, "onMessageEvent: receiveIceCandidate")
                    mWebRtcEngine?.receiveIceCandidate(
                        userBean.uid,
                        map["sdpMid"].toString(),
                        (map["sdpMLineIndex"] as Double).toInt(),
                        map["sdp"].toString()
                    )
                }
            }
        }
    }

    override fun onDestroy() {
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this)
        }
        super.onDestroy()
    }

}